
using System;
using System.IO.Ports;
using System.Threading;

namespace MySerialCommunication
{
    internal class SerialCommApp
    {
        private static bool isActive;
        private static SerialPort comDevice;

        // 主程序入口
        static void Main(string[] args)
        {
            SetupCommunication();
            RunChatSession();
        }

        private static void SetupCommunication()
        {
            comDevice = new SerialPort();
            
            Console.WriteLine("== 串口参数配置 ==");
            comDevice.PortName = GetPortSelection();
            comDevice.BaudRate = GetBaudRate();
            comDevice.Parity = GetParityType();
            comDevice.DataBits = GetDataBits();
            comDevice.StopBits = GetStopBits();
            comDevice.Handshake = GetHandshakeMode();

            comDevice.ReadTimeout = 500;
            comDevice.WriteTimeout = 500;
        }

        private static void RunChatSession()
        {
            try
            {
                comDevice.Open();
                isActive = true;

                var receiver = new Thread(ReceiveData);
                receiver.Start();

                Console.Write("\n请输入您的昵称：");
                string userName = Console.ReadLine();
                Console.WriteLine("输入 exit 退出程序\n");

                while (isActive)
                {
                    string input = Console.ReadLine();
                    if (IsExitCommand(input))
                    {
                        TerminateProgram();
                    }
                    else
                    {
                        SendFormattedMessage(userName, input);
                    }
                }

                receiver.Join();
            }
            finally
            {
                comDevice.Close();
            }
        }

        private static void ReceiveData()
        {
            while (isActive)
            {
                try
                {
                    string received = comDevice.ReadLine();
                    Console.WriteLine($"[接收] {DateTime.Now:HH:mm:ss} > {received}");
                }
                catch (TimeoutException)
                {
                    // 忽略超时异常
                }
            }
        }
        private static string GetPortSelection()
        {
            Console.WriteLine("\n可用端口列表：");
            foreach (var port in SerialPort.GetPortNames())
            {
                Console.WriteLine($"  - {port}");
            }

            Console.Write("请输入端口号（默认COM1）：");
            string selected = Console.ReadLine();
            
            return string.IsNullOrEmpty(selected) ? "COM1" : selected.ToUpper();
        }

        private static int GetBaudRate(int defaultRate = 9600)
        {
            Console.Write($"请输入波特率（默认{defaultRate}）：");
            string input = Console.ReadLine();
            return int.TryParse(input, out int result) ? result : defaultRate;
        }

        private static Parity GetParityType(Parity defaultType = Parity.None)
        {
            Console.WriteLine("\n校验方式选项：");
            foreach (var name in Enum.GetNames(typeof(Parity)))
            {
                Console.WriteLine($"  - {name}");
            }

            Console.Write($"选择校验方式（默认{defaultType}）：");
            string input = Console.ReadLine();
            return ParseEnum<Parity>(input, defaultType);
        }

        private static int GetDataBits(int defaultBits = 8)
        {
            Console.Write($"请输入数据位（5-8，默认{defaultBits}）：");
            string input = Console.ReadLine();
            return int.TryParse(input, out int result) 
                ? Math.Clamp(result, 5, 8) 
                : defaultBits;
        }

        private static StopBits GetStopBits(StopBits defaultStop = StopBits.One)
        {
            Console.WriteLine("\n停止位选项：");
            foreach (var name in Enum.GetNames(typeof(StopBits)))
            {
                Console.WriteLine($"  - {name}");
            }

            Console.Write($"选择停止位（默认{defaultStop}）：");
            string input = Console.ReadLine();
            return ParseEnum<StopBits>(input, defaultStop);
        }

        private static Handshake GetHandshakeMode(Handshake defaultMode = Handshake.None)
        {
            Console.WriteLine("\n流控模式选项：");
            foreach (var name in Enum.GetNames(typeof(Handshake)))
            {
                Console.WriteLine($"  - {name}");
            }

            Console.Write($"选择流控模式（默认{defaultMode}）：");
            string input = Console.ReadLine();
            return ParseEnum<Handshake>(input, defaultMode);
        }

        private static T ParseEnum<T>(string input, T defaultValue) where T : struct
        {
            return Enum.TryParse(input, true, out T result) ? result : defaultValue;
        }

        private static bool IsExitCommand(string input)
        {
            return input.Equals("exit", StringComparison.OrdinalIgnoreCase);
        }

        private static void TerminateProgram()
        {
            isActive = false;
            Console.WriteLine("程序正在关闭...");
        }

        private static void SendFormattedMessage(string user, string content)
        {
            string message = $"[{DateTime.Now:HH:mm:ss}] {user}: {content}";
            comDevice.WriteLine(message);
        }
    }
}